import inspect
import ctypes
import time
import threading


def _async_raise(tid, exctype):
    """Raises an exception in the threads with id tid"""
    if not inspect.isclass(exctype):
        raise TypeError("Only types can be raised (not instances)")
    res = ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(tid), ctypes.py_object(exctype))
    if res == 0:
        print("ValueError::invalid thread id")
        pass
        
    elif res != 1:
        # """if it returns a number greater than one, you're in trouble,
        # and you should call it again with exc=NULL to revert the effect"""
        ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)
        print('SystemError::PyThreadState_SetAsyncExc failed')


def stop_thread(thread):
    _async_raise(thread.ident, SystemExit)


class DownloaderManager:
    def __init__(self):
        self.downloader_list = []
        self.running_downloader = None

    def add_downloader(self, thread):
        self.downloader_list.append(thread)

    def mainloop(self):
        while 1:
            time.sleep(0.03)
            if self.running_downloader is None:
                if self.downloader_list:
                    self.running_downloader = self.downloader_list[0]
                    self.running_downloader.start()         # 传入的 Downloader 对象需要有 start 方法
                    self.downloader_list.pop(0)

            else:
                if self.running_downloader.percent == 1.00:     # Downloader 对象需含有 percent 属性 -> 下载进度
                    self.running_downloader = None


DownloaderManager = DownloaderManager()

t__ = threading.Thread(target=DownloaderManager.mainloop)
t__.setDaemon(True)
t__.start()
